using ImageCSharp.Core.Models;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using System;
using System.Collections.Generic;

namespace ImageCSharp.Core.Services
{
    /// <summary>
    /// 选择服务
    /// </summary>
    public class SelectionService
    {
        /// <summary>
        /// 魔术棒选择（基于颜色相似性）
        /// </summary>
        public static List<SixLabors.ImageSharp.Point> MagicWandSelect(Image<Rgba32> image, int startX, int startY, float tolerance = 0.1f)
        {
            var selectedPoints = new List<SixLabors.ImageSharp.Point>();
            var visited = new bool[image.Width, image.Height];
            
            if (startX < 0 || startX >= image.Width || startY < 0 || startY >= image.Height)
                return selectedPoints;

            var targetColor = image[startX, startY];
            var queue = new Queue<(int X, int Y)>();
            queue.Enqueue((startX, startY));
            visited[startX, startY] = true;

            while (queue.Count > 0)
            {
                var (x, y) = queue.Dequeue();
                selectedPoints.Add(new SixLabors.ImageSharp.Point(x, y));

                // 检查四个方向的相邻像素
                CheckAndAddNeighbor(x - 1, y);
                CheckAndAddNeighbor(x + 1, y);
                CheckAndAddNeighbor(x, y - 1);
                CheckAndAddNeighbor(x, y + 1);

                void CheckAndAddNeighbor(int nx, int ny)
                {
                    if (nx >= 0 && nx < image.Width && ny >= 0 && ny < image.Height && !visited[nx, ny])
                    {
                        var neighborColor = image[nx, ny];
                        if (ColorDistance(targetColor, neighborColor) <= tolerance)
                        {
                            visited[nx, ny] = true;
                            queue.Enqueue((nx, ny));
                        }
                    }
                }
            }

            return selectedPoints;
        }

        /// <summary>
        /// 计算颜色距离
        /// </summary>
        private static float ColorDistance(Rgba32 color1, Rgba32 color2)
        {
            float rDiff = color1.R - color2.R;
            float gDiff = color1.G - color2.G;
            float bDiff = color1.B - color2.B;
            
            return (float)Math.Sqrt(rDiff * rDiff + gDiff * gDiff + bDiff * bDiff) / 255.0f;
        }

        /// <summary>
        /// 将点列表转换为选择区域
        /// </summary>
        public static SixLabors.ImageSharp.RectangleF GetSelectionBounds(List<SixLabors.ImageSharp.Point> points)
        {
            if (points.Count == 0)
                return SixLabors.ImageSharp.RectangleF.Empty;

            int minX = int.MaxValue, maxX = int.MinValue;
            int minY = int.MaxValue, maxY = int.MinValue;

            foreach (var point in points)
            {
                minX = Math.Min(minX, point.X);
                maxX = Math.Max(maxX, point.X);
                minY = Math.Min(minY, point.Y);
                maxY = Math.Max(maxY, point.Y);
            }

            return new SixLabors.ImageSharp.RectangleF(minX, minY, maxX - minX + 1, maxY - minY + 1);
        }

        /// <summary>
        /// 创建选择遮罩
        /// </summary>
        public static bool[,] CreateSelectionMask(int width, int height, List<SixLabors.ImageSharp.Point> selectedPoints)
        {
            var mask = new bool[width, height];
            foreach (var point in selectedPoints)
            {
                if (point.X >= 0 && point.X < width && point.Y >= 0 && point.Y < height)
                {
                    mask[point.X, point.Y] = true;
                }
            }
            return mask;
        }
    }
}